package com.phf.listener;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import com.phf.common.core.annotation.NacosRefreshStaticField;
import com.purgeteam.dynamic.config.starter.annotation.EnableDynamicConfigEvent;
import com.purgeteam.dynamic.config.starter.event.ActionConfigEvent;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

@Slf4j
@Component
@EnableDynamicConfigEvent
public class NacosListener implements ApplicationListener<ActionConfigEvent> {

    @Autowired
    private ApplicationContext applicationContext;

    @SneakyThrows
    @Override
    public void onApplicationEvent(ActionConfigEvent environment) {
        Map<String, HashMap> map = environment.getPropertyMap();
        for (Map.Entry<String, HashMap> entry : map.entrySet()) {
            String key = entry.getKey();
            Map changeMap = entry.getValue();
            String before = String.valueOf(changeMap.get("before"));
            String after = String.valueOf(changeMap.get("after"));
            log.info("配置[key:{}]被改变，改变前before：{}，改变后after：{}",key,before,after);

            String[] configNameArr = key.split("\\.");
            String configPrefix = configNameArr[0];
            String configRealVal = configNameArr[configNameArr.length-1];

            AtomicReference<Class<?>> curClazz = new AtomicReference<>();
            Map<String, Object> refreshStaticFieldBeanMap = applicationContext.getBeansWithAnnotation(NacosRefreshStaticField.class);
            for (Map.Entry<String, Object> mapEntry : refreshStaticFieldBeanMap.entrySet()) {
                String beanName = mapEntry.getKey();
                if (ObjectUtil.isEmpty(beanName)) {
                    continue;
                }

                String fullClassName = refreshStaticFieldBeanMap.get(beanName).toString().split("@")[0];
                Class<?> refreshStaticFieldClass;
                try {
                    refreshStaticFieldClass = Class.forName(fullClassName);
                } catch (ClassNotFoundException e) {
                    throw new ClassNotFoundException("监听nacos刷新当前静态类属性,未找到当前类",e);
                }
                NacosRefreshStaticField refreshStaticConfig = refreshStaticFieldClass.getAnnotation(NacosRefreshStaticField.class);
                if (Objects.nonNull(refreshStaticConfig) && refreshStaticConfig.configPrefix().equalsIgnoreCase(configPrefix)) {
                    curClazz.set(refreshStaticFieldClass);
                }
            }
            Class<?> aClass = curClazz.get();
            if (Objects.isNull(aClass)) {
                return;
            }

            // 利用反射动态更新 静态变量
            log.info("刷新当前配置 更新当前类[{}] 静态属性 [{}]",aClass.getSimpleName(),configRealVal);
            ReflectUtil.setFieldValue(aClass,configRealVal,after);

        }

    }
}
